from pyModbusTCP.client import ModbusClient
from tools.hd_logger import HdLogger

"""
1、允许拍照D500，
3.  你再反馈我拍照完成（D501）
2. 你反馈一个OK或者NG（D502 or D503)

请注意，Modbus寄存器地址从0开始，而许多PLC会将第一个寄存器的地址标记为1，所以你可能需要对地址减1。
如果你的PLC将D100表示为Modbus地址100，那么你可能需要读取地址99
"""


class PlcInstance(object):
    def __init__(self):
        self.ip = "192.168.1.88"
        self.port = 502
        self.errorMsg = ""
        self.logger = HdLogger()
        self.plcClient = None
        self.connectedStatus = "已断开"

    def ConnectionPlc(self):
        try:
            if self.plcClient is None:
                self.plcClient = ModbusClient(host=self.ip, port=self.port, auto_open=True, timeout=2)
            connectedRes = self.plcClient.open()
            if connectedRes:
                self.connectedStatus = "已连接"
            return connectedRes
        except Exception as e:
            print("in ConnectionPlc() Error: {}".format(str(e)))
            self.logger.debug("in ConnectionPlc() Error: {}".format(str(e)))
            self.connectedStatus = "已断开"
            self.plcClient = None
            return False

    def CheckPlcIsOnline(self):
        try:
            if self.plcClient is not None:
                return self.plcClient.is_open
        except Exception as e:
            self.connectedStatus = "已断开"
            self.plcClient = None
            print("in CheckPlcIsOnline() Error:{}".format(str(e)))
            self.logger.debug("in CheckPlcIsOnline() Error:{}".format(str(e)))
            return False

    def __del__(self):
        try:
            self.Close()
        except Exception as e:
            print("in PlcInstance(), error:{}".format(e))

    def Close(self):
        if self.plcClient is not None:
            self.plcClient.close()

    # 获取PLC拍照信号
    def GetAllowTakePicture(self):
        try:
            # 读取D500的值,要从500开始读取
            registers = self.plcClient.read_holding_registers(500, 1)
            if registers is not None:
                return 0, registers[0]
            else:
                return -1, "读取错误,返回的registers为None"
        except Exception as e:
            loggerInfo = "in GetAllowTakePicture() Error:{}".format(str(e))
            print(loggerInfo)
            self.logger.debug(loggerInfo)
            return -1, None

    def GetPlcState(self):
        """
        获取Plc的状态,如果是停机,就是1,2为运行中,0为待机
        """
        try:

            registers = self.plcClient.read_holding_registers(505, 1)
            if registers is not None:
                return 0, registers[0]
            else:
                return 0, "读取错误,返回的registers为None"
        except Exception as e:
            loggerInfo = "in GetAllowTakePicture() Error:{}".format(str(e))
            print(loggerInfo)
            self.logger.debug(loggerInfo)
            return -1, None

    # 复位发送D600 = 2
    def WriteResetCommand(self):
        try:
            result = self.plcClient.write_single_register(600, 2)
            return "ok" if result else "PLC通信异常,D600=2写入失败"
        except Exception as e:
            loggerInfo = "in GetAllowTakePicture() Error:{}".format(str(e))
            print(loggerInfo)
            self.logger.debug(loggerInfo)
            return loggerInfo


    def WriteResetAlarmCommand(self):
        try:
            result = self.plcClient.write_single_register(601, 2)
            return "ok" if result else "PLC通信异常,D601=2写入失败"
        except Exception as e:
            loggerInfo = "in GetAllowTakePicture() Error:{}".format(str(e))
            print(loggerInfo)
            self.logger.debug(loggerInfo)
            return loggerInfo


    # 清除PLC拍照信号
    def SetAllowTakePictureClear(self):
        try:
            result = self.plcClient.write_single_register(500, 0)
            return result
        except Exception as e:
            loggerInfo = "in GetAllowTakePicture() Error:{}".format(str(e))
            print(loggerInfo)
            self.logger.debug(loggerInfo)
            return False

    def TakePicFinish(self):
        try:
            # 读取D500的值,要从499开始读取
            result = self.plcClient.write_single_register(501, 1)
            return result
        except Exception as e:
            loggerInfo = "in TakePicFinish() Error:{}".format(str(e))
            print(loggerInfo)
            self.logger.debug(loggerInfo)
            return False

    def SetOkResult(self):
        try:
            # 读取D500的值,要从499开始读取
            result = self.plcClient.write_single_register(502, 1)
            return result
        except Exception as e:
            loggerInfo = "in SetOkResult() Error:{}".format(str(e))
            print(loggerInfo)
            self.logger.debug(loggerInfo)
            return False

    def SetNgResult(self):
        try:
            # 读取D500的值,要从499开始读取
            result1 = self.plcClient.write_single_register(502, 2)
            return result1
        except Exception as e:
            loggerInfo = "in SetNgResult() Error:{}".format(str(e))
            print(loggerInfo)
            self.logger.debug(loggerInfo)
            return False


if __name__ == '__main__':
    instanace = PlcInstance()
    res = instanace.ConnectionPlc()
    print("连接Res = {}".format(res))
    ret, val = instanace.GetAllowTakePicture()
    print("获取拍照信号: res = {},val = {}".format(ret, val))
    result = instanace.SetAllowTakePictureClear()
    print("清空拍照信号结果: {}".format(result))
    result = instanace.TakePicFinish()
    print("拍照结束信号: {}".format(result))
    result = instanace.SetOkResult()
    print("设置OK信号: {}".format(result))
    result = instanace.SetNgResult()
    print("设置NG信号: {}".format(result))
